﻿using System;
using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Data;
using System.Text;
using System.Web.UI;
using Microsoft.SharePoint.Utilities;

namespace Demo.Calendar.CustomCalendar
{
    [ToolboxItemAttribute(false)]
    public partial class CustomCalendar : Microsoft.SharePoint.WebPartPages.WebPart
    {
        // Specifies the calendar for the add event. 
        static SPSite site = SPContext.Current.Site;
        private string strListName = "RollupCalendar";
        [WebBrowsable(true),
        WebDisplayName("Top Level Calendar Name"),
        WebDescription("Top Level Calendar Name"),
        Personalizable(PersonalizationScope.Shared),
        Category("Settings"),
        DefaultValue("Calendar Tools")
        ]
        public string _strListName
        {
            get { return strListName; }
            set { strListName = value; }
        }


        //public CustomCalendarWebPart()
        //{
        //}


        protected override void CreateChildControls()
        {
            string site = SPContext.Current.Site.Url;


            Microsoft.SharePoint.WebControls.CssRegistration cssLink = new Microsoft.SharePoint.WebControls.CssRegistration();
            cssLink.Name = site + "/Style Library/Demo/DemoCalendar.css";
            this.Page.Header.Controls.Add(cssLink);

            //this script add general javascript for the web part like showModal
            //ScriptLink scriptt1 = new ScriptLink();
            //scriptt1.Name = "~sitecollection/Scripts/calScripts.js";
            //scriptt1.Defer = true;
            //if (!this.Page.Header.Controls.Contains(scriptt1))
            //    this.Page.Header.Controls.Add(scriptt1);




            base.CreateChildControls();
            // Current web
            SPWeb web = SPContext.Current.Web;
            // List data
            DataTable results = GetQueryData(web);
            // Calendar Item Collection
            SPCalendarItemCollection items;
            if (results.Rows.Count > 0)
            {
                items = GetCalendarItems(web, results);
            }
            else
            {
                // Render header firstly:
                StringBuilder noResults = new StringBuilder();
                noResults.AppendLine("");
                noResults.AppendLine("");
                noResults.AppendLine("<font color='#05C4D8' size='4'>No Data Returned</font>");
                noResults.AppendLine("");
                Controls.Add(new LiteralControl(noResults.ToString()));
                return;
            }


            this.spCalendarView.EnableViewState = true;


            // Calendar Type
            if (!string.IsNullOrEmpty(Page.Request["CalendarPeriod"]))
            {
                this.spCalendarView.ViewType = GetCalendarType(Page.Request["CalendarPeriod"]);
            }


            // Binds a datasource to the SPCalendarView
            spCalendarView.DataSource = items;
            spCalendarView.DataBind();


            SPSecurity.RunWithElevatedPrivileges(
               delegate()
               {
                   // Check if current user can add events:
                   bool blnCanAddEvents = false;


                   using (web = SPContext.Current.Site.OpenWeb())
                   {
                       try
                       {
                           bool isHavePermissions = web.DoesUserHavePermissions(SPBasePermissions.AddListItems);


                           if (isHavePermissions)
                           {
                               blnCanAddEvents = true;
                           }
                       }
                       catch
                       {
                       }
                   }


                   // Render header firstly:
                   StringBuilder sbHeader = new StringBuilder();
                   sbHeader.AppendLine("");
                   sbHeader.AppendLine("");
                   sbHeader.AppendLine("<font color='#05C4D8' size='4'> </font>"); sbHeader.AppendLine("");
                   Controls.Add(new LiteralControl(sbHeader.ToString()));


                   //Render calendar secondly:     
                   Controls.Add(spCalendarView);


                   // Append Operation legend:

                   StringBuilder sbLegend = new StringBuilder();
                   sbLegend.AppendLine("<table align='center' width='100%' border='0'>");
                   sbLegend.AppendLine("<tr>");
                   sbLegend.AppendLine("<td width='50%' align='left' valign='top'>");
               
                   sbLegend.AppendLine("<b><u>Operation:</u></b><br /><br />");
                   string url = string.Format("{1}/Lists/{0}/NewForm.aspx", strListName, web.Url);

                   string java = string.Format("<li><a href=\"#\" onclick=\"javascript:showModal('Add Events', '{0}')\" >Add New Events</a></li>", url);

                   if (blnCanAddEvents)
                   {
                       //modal
                       sbLegend.AppendLine(string.Format("{0}", java));
                       //no modal
                       //sbLegend.AppendLine(String.Format("<li><a href=\"{1}/Lists/{0}/NewForm.aspx\">Add New Event</a></li>", strListName, web.Url));


                   }
                   sbLegend.AppendLine(String.Format("<li><a href='{1}/Lists/{0}'>View the Full Calendar</a></li>", strListName, web.Url));
                   sbLegend.AppendLine("</td></tr></table>");
                   Controls.Add(new LiteralControl(sbLegend.ToString()));
               });
        }
        //sbLegend.AppendLine(String.Format("<li><a href=\"{1}/Lists/{0}/NewForm.aspx\">Add New Event</a></li>", strListName, web.Url));
        //<a href="#" onclick="javascript:showModal('Obligations', '/matt/Land/Lists/Obligations/calendar.aspx');">Obligations</a>

        /// <summary>
        /// Executes the query against the web and returns 
        /// results as DataTable.
        /// </summary>
        /// <param name="web">The web that is queried.</param>
        /// <returns>Query results as DataTable.</returns>
        private DataTable GetQueryData(SPWeb web)
        {
            var query = new SPSiteDataQuery();

            //no need to grab all calendars thus no servertemplate
            //query.Lists = "<Lists ServerTemplate=\"106\" />";
            //no need to grad lists by id need to know all lists before hand
            //            query.Lists = @"<Lists>
            //                      <List ID='{080BA3CB-9D7F-4E6B-AE02-2E5BFB79EF91}' />
            //                      <List ID='{B65A63B6-B857-423A-AE22-AA7957E78157}' />
            //                  </Lists>";
            //we are going to grab by content type thus nomral calendars will not be caught in the spsitedataquery
            SPContentType cTypeCollection = web.ContentTypes["RollUpCalendarContentType"];





            string where = string.Format(
                              @"<Where>
                    <BeginsWith>
                        <FieldRef Name='ContentTypeId'/>
                             <Value Type='Text'>{0}</Value>
                     </BeginsWith>
                  </Where>", cTypeCollection.Id);

            // Set the query string.
            query.Query = where;



            query.Webs = "<Webs Scope='SiteCollection' />";
            query.ViewFields = "<FieldRef Name='Title' />";
            query.ViewFields += "<FieldRef Name='ID' />";
            query.ViewFields += "<FieldRef Name='EventDate' />";
            query.ViewFields += "<FieldRef Name='EndDate' />";
            query.ViewFields += "<FieldRef Name='Location' />";
            query.ViewFields += "<FieldRef Name='Description' />";
            query.ViewFields += "<FieldRef Name='fAllDayEvent' />";
            query.ViewFields += "<FieldRef Name='fRecurrence' />";
            query.ViewFields += "<FieldRef Name='MilCategory' />";
            query.ViewFields += "<FieldRef Name='ContentType'/>";
            query.RowLimit = 100;


            return web.GetSiteData(query);
        }

        private SPCalendarItemCollection GetCalendarItems(SPWeb web, DataTable results)
        {
            // Create a new collection for the calendar items
            var items = new SPCalendarItemCollection();
            // SPCalendar Item
            SPCalendarItem item = null;


            #region Calendar Items which is got from the results
            // Loop results to get Calendar Item Information
            foreach (DataRow row in results.Rows)
            {
                // List Guid
                string guid = row["ListId"].ToString();



                // List
                SPList list = null;
                string site1 = null;
                string webid = row["WebId"].ToString();
                Guid webGuid = new Guid(webid);
                using (SPSite site = new SPSite(web.Site.ID))
                {
                    using (SPWeb subWeb = site.OpenWeb(webGuid))
                    {
                        Guid lGuid = new Guid(guid);
                        list = subWeb.Lists[lGuid];
                        site1 = subWeb.Title;
                    }
                }



                item = new SPCalendarItem();


                foreach (SPForm form in list.Forms)
                {
                    // Display Form Url

                    if (form.Type == PAGETYPE.PAGE_DISPLAYFORM)
                    {
                        item.DisplayFormUrl = form.ServerRelativeUrl;
                        break;
                    }
                }





                item.ItemID = row["ID"] as string;
                item.StartDate = DateTime.Parse(row["EventDate"] as string);
                item.EndDate = DateTime.Parse(row["EndDate"] as string);
                item.hasEndDate = true;
                item.Title = site1 + " " + row["Title"] as string;
                item.Location = row["Location"] as string;
                item.Description = row["Description"] as string;
                item.IsAllDayEvent = (int.Parse(row["fAllDayEvent"] as string) != 0);
                item.IsRecurrence = (int.Parse(row["fRecurrence"] as string) != 0);
                item.CalendarType = Convert.ToInt32(SPCalendarType.Gregorian);

                items.Add(item);
            }
            #endregion



            return items;
        }

        /// <summary>
        /// Gets the type of the calendar view.
        /// </summary>
        /// <param name="type">The type to be checked.</param>
        /// <returns>Correct view type of calendar.</returns>
        protected static string GetCalendarType(string type)
        {
            if (type == null)
                type = string.Empty;
            switch (type.ToLower())
            {
                case "day":
                    return "day";
                case "week":
                    return "week";
                case "timeline":
                    return "timeline";
                default:
                    return "month";
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            InitializeControl();


        }

        protected void Page_Load(object sender, EventArgs e)
        {


        }
    }
}